import 'dart:io';

import 'package:auto_route/auto_route.dart';
import 'package:casdon/app/config/env/common_config.dart';
import 'package:casdon/core/auth/auth_storage.dart';
import 'package:casdon/core/extentions/string_validation.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/modules/device/ui/screen/tm_bind_result_screen.dart';

import 'package:casdon/auto_router.dart';

import 'package:casdon/modules/device/application/notification/product_category_notifier.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

// 扫码控制器
final scannerControllerProvider = Provider.autoDispose<MobileScannerController>(
  (ref) {
    final controller = MobileScannerController();
    ref.onDispose(() => controller.dispose());
    return controller;
  },
);

// 图片选择器
final imagePickerProvider = Provider((ref) => ImagePicker());

// 扫码结果状态
final scanResultProvider = StateProvider<String?>((ref) => null);

// 图片扫码处理器
final imageScanProvider = FutureProvider.family<bool, File>((
  ref,
  imageFile,
) async {
  try {
    final controller = ref.read(scannerControllerProvider);
    final barcodeCapture = await controller.analyzeImage(imageFile.path);
    if (barcodeCapture == null) {
      return false;
    } else {
      return barcodeCapture.barcodes.isNotEmpty;
    }
  } catch (e) {
    throw Exception('图片解析失败: $e');
  }
});

// 扫码结果处理 Provider
final scanResultHandlerProvider = Provider.autoDispose<ScanResultHandler>((
  ref,
) {
  return ScanResultHandler(ref);
});

/// 天猫账号绑定成功事件，用于从绑定页面回传到扫码流程
final tmBindSuccessProvider = StateProvider.autoDispose<bool>((ref) => false);

class ScanResultHandler {
  final Ref ref;

  ScanResultHandler(this.ref);

  Future<void> onTMBindSuccess(BuildContext context) async {
    Log.i('天猫绑定成功事件已接收，后续处理可在此触发');
    String qrcode = ref.read(scanResultProvider.notifier).state ?? '';
    if (qrcode.contains(CommonConfig.qrcode_tm)) {
      final tuyaUrl = qrcode.split(';&;').last;
      if (tuyaUrl.startsWith(CommonConfig.qrcode_tuya)) {
        await _handleTuyaCodePairNet(context, tuyaUrl);
      }
    }
  }

  Future<bool> handleBarcode(BuildContext context, Barcode barcode) async {
    try {
      final rawValue = barcode.rawValue?.trim();
      if (rawValue == null || rawValue.isEmpty) {
        return false;
      }

      if (rawValue.contains(CommonConfig.qrcode_ciot)) {
        await _handleCiotPairNet(rawValue);
        return true;
      }
      if (rawValue.startsWith(CommonConfig.qrcode_tuya)) {
        await _handleTuyaCodePairNet(context, rawValue);
        return true;
      }

      if (rawValue.contains(CommonConfig.qrcode_tm)) {
        await _handleTianMaoPairNet(context, rawValue);
        return true;
      }
      if (rawValue.contains(CommonConfig.qrcode_product)) {
        await _handleOpenWebPage(context, rawValue);
        return true;
      }
      if (rawValue.contains(CommonConfig.qrcode_cloud_recipe)) {
        await _handleOpenWebPage(context, rawValue);
        return true;
      }
      if (rawValue.contains(CommonConfig.qrcode_local_recipe)) {
        await _handleOpenWebPage(context, rawValue);
        return true;
      }
      return false;
    } catch (e) {
      Log.e('处理扫码结果失败: $e', e, StackTrace.current);
      return false;
    }
  }

  Future<void> _handleCiotPairNet(String s) async {
    Log.i("_handleCiotPairNet ${s}");
  }

  Future<void> _handleTuyaCodePairNet(BuildContext context, String code) async {
    Log.i("_handleTuyaCodePairNet ${code}");
    if (code.isNotEmpty) {
      if (context.mounted == false) {
        return;
      }
      // 有2个地方可能会调用到这里，1，正常扫码绑定，2 天猫扫码验证成功后 调用，此时最上层页面 不是该页面，所以要用router.root
      context.router.root.push(QrDeviceProgressRoute(qrcode: code));
    }
  }

  Future<bool> _handleTianMaoPairNet(BuildContext context, String url) async {
    Log.i("_handleTianMaoPairNet ${url}");

    try {
      // 1，判断账户名是否是邮箱，是则toast：请用手机号登录，否则进入下一步
      final authStorage = ref.read(authStorageProvider.notifier);
      final userAccount = await authStorage.getUserAccount();

      if (userAccount == null || userAccount.trim().isEmpty) {
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('请先登录')));
        }
        return false;
      }

      if (userAccount.isEmail()) {
        if (context.mounted) {
          await Navigator.of(context).push(
            MaterialPageRoute(
              builder: (_) => TMBindResultScreen(errorMessage: ""),
            ),
          );
        }
        return false;
      }

      // 2，解析URL，获取clientId 和 code
      final uri = Uri.parse(url);

      // 从 result 中提取 tuyaUrl
      String? tuyaUrl;
      final resultString = url;
      if (resultString.contains(';&;')) {
        final index = resultString.indexOf(';&;');
        if (index != -1 && index + 3 < resultString.length) {
          tuyaUrl = resultString.substring(index + 3);
          Log.i('提取到 tuyaUrl: $tuyaUrl');
        }
      }
      final clientId = uri.queryParameters['clientId'];
      final code = uri.queryParameters['code'];

      if (clientId == null ||
          clientId.isEmpty ||
          code == null ||
          code.isEmpty) {
        Log.e('解析URL失败，clientId或code为空', Object(), StackTrace.current);
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('二维码格式错误')));
        }
        return false;
      }

      Log.i('解析URL成功: clientId=$clientId, code=$code');

      // 3，获取账户userId；调用接口：api/v1/aliGenie/authLoginWithThirdUserInfo
      final userId = await authStorage.getUserId();
      if (userId == null || userId.trim().isEmpty) {
        Log.e('获取userId失败', Object(), StackTrace.current);
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('获取用户信息失败')));
        }
        return false;
      }

      final deviceRepository = ref.read(deviceRepositoryProvider);
      final authResult = await deviceRepository.getAliGenieAuthLogin(
        userId: userId,
      );

      // 检查返回结果
      if (authResult == null) {
        Log.e('天猫精灵三方登录失败：返回结果为空', Object(), StackTrace.current);
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('二维码已过期')));
        }
        return false;
      }

      // 获取 sessionId
      String? sessionId;
      if (authResult.dataObj != null) {
        sessionId = authResult.dataObj!['sessionId'] as String?;
        if (sessionId != null) {
          Log.i('天猫精灵扫码，获取到 sessionId: $sessionId');

          // TODO: 保存 sessionId 到合适的位置（如 SharedPreferences 或状态管理）
        } else {
          return false;
        }
      }

      // 处理成功情况：success == true 且 result != null 且 loginStateAccessToken != null
      if (authResult.success &&
          authResult.result != null &&
          authResult.result!.loginStateAccessToken != null) {
        final accessToken = authResult.result!.loginStateAccessToken!;
        Log.i('天猫精灵三方登录成功，accessToken: $accessToken');

        // 调用认证方法 ecologyOpennessAuthenticate
        final authenticateResult = await deviceRepository
            .ecologyOpennessAuthenticate(loginStateAccessToken: accessToken);

        // 检查认证返回结果
        if (authenticateResult == null) {
          Log.e('生态开放认证失败：返回结果为空', Object(), StackTrace.current);
          if (context.mounted) {
            ScaffoldMessenger.of(
              context,
            ).showSnackBar(const SnackBar(content: Text('认证失败，请重试')));
          }
          return false;
        }

        // 处理认证成功情况：result != null 且 userOpenId != null
        if (authenticateResult.result != null &&
            authenticateResult.result!.userOpenId != null &&
            tuyaUrl != null &&
            tuyaUrl.isNotEmpty) {
          final userOpenId = authenticateResult.result!.userOpenId!;
          Log.i('生态开放认证成功，userOpenId: $userOpenId');

          // 调用 scanBind 方法
          final scanResult = await _scanBind(
            context: context,
            userOpenId: userOpenId,
            clientId: clientId,
            code: code,
            tuyaUrl: tuyaUrl,
          );

          return scanResult;
        } else {
          Log.e(
            '生态开放认证失败：result 或 userOpenId 为空',
            Object(),
            StackTrace.current,
          );
          if (context.mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('认证失败: ${authenticateResult.message ?? '未知错误'}'),
              ),
            );
          }
          return false;
        }
      }
      // 处理失败情况：code == 5140001，需要跳转到绑定页面
      else if (!authResult.success && authResult.code == 5140001) {
        Log.i('需要绑定账号，code: ${authResult.code}');
        if (context.mounted) {
          GetBindCatCodeRoute(sessionId: sessionId!).push(context);
        }
        return false;
      }
      // 其他失败情况
      else {
        Log.e(
          '天猫精灵三方登录失败: code=${authResult.code}, message=${authResult.message}',
          Object(),
          StackTrace.current,
        );
        if (context.mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('登录失败: ${authResult.message ?? '未知错误'}')),
          );
        }
        return false;
      }
    } catch (e, st) {
      Log.e('天猫精灵配网绑定失败: $e', e, st);
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('设备绑定失败: ${e.toString()}')));
      }
      return false;
    }
  }

  Future<bool> _scanBind({
    required BuildContext context,
    required String userOpenId,
    required String clientId,
    required String code,
    required String tuyaUrl,
  }) async {
    try {
      final deviceRepository = ref.read(deviceRepositoryProvider);
      final scanResult = await deviceRepository.scanCodeBind(
        userOpenId: userOpenId,
        clientId: clientId,
        code: code,
      );

      // 检查返回结果
      if (scanResult == null) {
        Log.e('扫码绑定失败：返回结果为空', Object(), StackTrace.current);
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('绑定失败，请重试')));
        }
        return false;
      }

      // 处理成功情况：result != null 且 userOpenId != null
      if (scanResult.result != null && scanResult.result!.userOpenId != null) {
        // 如果提取到 tuyaUrl，调用配网方法
        if (tuyaUrl.isNotEmpty) {
          if (context.mounted == false) {
            return false;
          }
          _handleTuyaCodePairNet(context, tuyaUrl);
        }
        return true;
      } else {
        // 处理失败情况
        final errorMessage = scanResult.message ?? '绑定失败';
        Log.e('扫码绑定失败: $errorMessage', Object(), StackTrace.current);
        if (context.mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            scanResult.code == 800000
                ? const SnackBar(content: Text("二维码已过期，请重试"))
                : const SnackBar(content: Text("绑定失败，请重试")),
          );
        }
        return false;
      }
    } catch (e, st) {
      Log.e('扫码绑定异常: $e', e, st);
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('绑定失败: ${e.toString()}')));
      }
      return false;
    }
  }

  Future<void> _handleOpenWebPage(BuildContext context, String s) async {
    Log.i("_handleProductNet ${s}");
    await WebPageRoute(url: s, title: '').push(context);
  }
}
